/*
 * $RCSfile: Arguments.java,v $
 * $Revision: 1.1 $
 * $Date: 2010-06-21 $
 *
 * Copyright (C) 2008 Skin, Inc. All rights reserved.
 *
 * This software is the proprietary information of Skin, Inc.
 * Use is subject to license terms.
 */
package com.skin.webcat.config;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>Title: Arguments</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2006</p>
 * @author xuesong.net
 * @version 1.0
 */
public class Arguments {
    /**
     * @param arguments
     * @return String[]
     */
    public static String[] parse(String arguments) {
        String temp = arguments;

        if(arguments != null) {
            temp = arguments.trim();
        }
        else {
            temp = "";
        }

        if(temp.length() < 1) {
            return new String[0];
        }

        int i = 0;
        int length = temp.length();
        StringBuilder buffer = new StringBuilder();
        List<String> list = new ArrayList<String>();

        while(i < length) {
            char c = temp.charAt(i);

            if(c == '"' || c == '\'') {
                i = next(temp, buffer, i + 1, c);

                if(buffer.length() > 0) {
                    list.add(buffer.toString());
                    buffer.setLength(0);
                }
            }
            else if(c <= ' ') {
                while(i < length) {
                    c = temp.charAt(i);

                    if(c > ' ') {
                        break;
                    }
                    i++;
                }
            }
            else {
                i = next(temp, buffer, i, ' ');

                if(buffer.length() > 0) {
                    list.add(buffer.toString());
                    buffer.setLength(0);
                }
            }
        }
        String[] args = new String[list.size()];
        return list.toArray(args);
    }

    /**
     * @param args
     * @param offset
     * @param c
     * @return String
     */
    private static int next(String args, StringBuilder buffer, int offset, char e) {
        int i = offset;
        int length = args.length();

        while(i < length) {
            char c = args.charAt(i);

            if(c == e) {
                i++;
                break;
            }

            if(c == '\\' && i + 1 < length) {
                i++;
                c = args.charAt(i);

                switch(c) {
                    case 'n': {
                        i++;
                        buffer.append('\n');
                        break;
                    }
                    case 't': {
                        i++;
                        buffer.append('\t');
                        break;
                    }
                    case 'b': {
                        i++;
                        buffer.append('\b');
                        break;
                    }
                    case 'r': {
                        i++;
                        buffer.append('\r');
                        break;
                    }
                    case 'f': {
                        i++;
                        buffer.append('\f');
                        break;
                    }
                    case '\'': {
                        i++;
                        buffer.append('\'');
                        break;
                    }
                    case '\"': {
                        i++;
                        buffer.append('\"');
                        break;
                    }
                    case '\\': {
                        i++;
                        buffer.append('\\');
                        break;
                    }
                    case 'u': {
                        if(i + 4 < length) {
                            String hex = new String(args.substring(i + 1, i + 5));

                            try {
                                Integer value = Integer.parseInt(hex, 16);
                                buffer.append((char)(value.intValue()));
                            }
                            catch(NumberFormatException ex) {
                            }
                            i = i + 5;
                        }
                        else {
                            buffer.append("\\u");
                            i++;
                        }
                        break;
                    }
                    case '0': {
                        if(i + 2 < length) {
                            String oct = new String(args.substring(i + 1, i + 3));

                            try {
                                Integer value = Integer.parseInt(oct, 8);
                                buffer.append((char)(value.intValue()));
                            }
                            catch(NumberFormatException ex) {
                            }
                            i = i + 3;
                        }
                        else {
                            buffer.append("\\0");
                            i++;
                        }
                        break;
                    }
                    case 'x': {
                        if(i + 2 < length) {
                            String hex = new String(args.substring(i + 1, i + 3));

                            try {
                                Integer value = Integer.parseInt(hex, 16);
                                buffer.append((char)(value.intValue()));
                            }
                            catch(NumberFormatException ex) {
                            }
                            i = i + 3;
                        }
                        else {
                            buffer.append("\\0");
                            i++;
                        }
                        break;
                    }
                    default: {
                        i++;
                        buffer.append("\\");
                        buffer.append(c);
                        break;
                    }
                }
            }
            else {
                buffer.append(c);
                i++;
            }
        }
        return i;
    }
}
